package org.opu.doc2db.document.txtdoc.io;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.List;

import org.opu.doc2db.document.datadocument.Document;
import org.opu.doc2db.document.datadocument.Paragraph;
import org.opu.doc2db.document.datadocument.Table;
import org.opu.doc2db.document.datadocument.TableCell;
import org.opu.doc2db.document.datadocument.TableRow;
import org.opu.doc2db.document.datadocument.TextParagraph;
import org.opu.doc2db.document.datadocument.io.DocumentWriter;

public class TextDocumentWriter implements DocumentWriter {

    /** ' ' */
    public static final char SPACE = ' ';
    /** '-' */
    public static final char ROW_SEPARATOR = '-';
    /** '|' */
    public static final char CEL_SEPARATOR = '|';
    /** '+' */
    public static final char ROW_DELIM_SEPARATOR = '+';
    private Document document;
    private SettingsCalculator calculator;

    public TextDocumentWriter(Document document) {
        this.document = document;
        calculator = new SettingsCalculator();
    }

    @Override
    public void write(OutputStream out) throws IOException {
        write(new BufferedWriter(new OutputStreamWriter(out)));
    }

    @Override
    public void write(Writer writer) throws IOException {
        for (Paragraph p : document) {
            if (p instanceof Table) {
                processeTable((Table) p, writer);
            } else {
                if (!(p instanceof TextParagraph)) {
                    System.err.println("");
                }
                String text = p.getText();
                writeLine(text, writer);
            }
        }
        writer.close();
    }

    @Override
    public void write(File file) throws IOException {
        write(new BufferedWriter(new FileWriter(file)));
    }

    private void writeLine(String line, Writer writer) throws IOException {
        writer.write(calculator.getNewLine(line));
    }

    private void processeTable(Table table, Writer writer) throws IOException {
        int rIter = 0;
        int cIter = 0;

        Integer[] nullCollumn = calculator.nullCollumn(table);
        int tableWidth = calculator.tableWidth(table);
        int[] columnWidth = calculator.columnWidth(table);

        writeLine(calculator.add(null, ROW_SEPARATOR, tableWidth), writer);
        TableColumnWriter collumnWriter = new TableColumnWriter(calculator);
        for (TableRow row : table) {
            cIter = 0;
            collumnWriter.addNewRow();

            for (TableCell cell : row) {

                if (calculator.isIn(cIter, nullCollumn)) {
                    collumnWriter.addNewCell(calculator.toList(null, cell, cIter > 0, false), 1);
                } else if (cell.isVisible()) {
                    String fch = cIter > 0 ? "" + ROW_DELIM_SEPARATOR : "";
                    String str = calculator.add(null, ROW_SEPARATOR, columnWidth[cIter]);

                    List<String> add = rIter > 0 ? Arrays.asList(fch + str) : null;

                    List<String> lst = calculator.toList(add, cell, cIter > 0, false);

                    collumnWriter.addNewCell(lst, cell.getHsplit());
                } else if (!cell.isVisible()) {
                    collumnWriter.addNewCell(null, cell.getHsplit());
                }

                cIter++;
            }

            rIter++;
        }

        writer.write(collumnWriter.toString());
        writeLine(calculator.add(null, ROW_SEPARATOR, tableWidth), writer);
    }
}
